package com.yl.mybatis.executor.statement;

import com.yl.mybatis.binding.MapperMethod;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;

/**
 * 这个类应该在result包下，但是放result下面idea会抽风加载不到
 */
public class DefaultResultSetHandler {

    public   <T> T handle(PreparedStatement pstmt, MapperMethod mapperMethod, Object o) throws Exception {

        //-----这段代码可以封装成ObjectFactory,参考mybatis的DefaultObjectFactory
        Constructor constructor;
        try {
            constructor = mapperMethod.getType().getDeclaredConstructor();
            if (!constructor.isAccessible()) {
                constructor.setAccessible(true);
            }
        }catch (Exception e){
            throw new InterruptedException("没有无参构造方法");
        }
        Object resultObj =  constructor.newInstance();


        ResultSet rs = pstmt.getResultSet();
        if (rs.next()) {
            int i = 0;
            for (Field field : resultObj.getClass().getDeclaredFields()) {
                //通过set方法进行反射赋值
                setValue(resultObj, field, rs ,i);
            }
        }
        return (T) resultObj;
    }

    private void setValue(Object resultObj, Field field, ResultSet rs, int i) throws NoSuchMethodException, SQLException, InvocationTargetException, IllegalAccessException {
        Method setMethod = resultObj.getClass().getMethod("set" + upperCapital(field.getName()), field.getType());
        setMethod.invoke(resultObj, getResult(field,rs));
    }

    private String upperCapital(String name) {
        String first = name.substring(0, 1);
        String tail = name.substring(1);
        return first.toUpperCase() + tail;
    }

    private Object getResult(Field field, ResultSet rs) throws SQLException {
        Class<?> type = field.getType();
        if(Integer.class == type){
            return rs.getInt(field.getName());
        }
        if(String.class == type){
            return rs.getString(field.getName());
        }
        if(Long.class==type){
            return  rs.getLong(field.getName());
        }
        return rs.getString(field.getName());
    }


}
